package com.simp.run;

import com.baomidou.mybatisplus.annotation.TableName;
import com.simp.entity.*;
import com.simp.utils.ClassUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 将实体类子集加载至bean中
 *
 * @author pan.shun
 * @since 2022/3/19 21:42
 */
@Slf4j
@Component
public class EntityChildrenClassBean {

    private Map<String, Class> entityClass = new HashMap<>();

    private Map<String, Class> preEntityClass = new HashMap<>();

    public Map<String, Class> getEntityClass() {
        return entityClass;
    }


    /**
     * 后期如果有添加的实体类，请手动添加进去
     */
    private List<Class> aClassList = new ArrayList<>(
            Arrays.asList(
                    SysConfigEntity.class,
                    SysDictEntity.class,
                    SysLogEntity.class,
                    SysThemeEntity.class,
                    SysUserEntity.class,
                    SysScriptEntity.class,
                    SysCategoryEntity.class
            )

    );

    private void terminalSolve() {
        aClassList.forEach(this::initClass);
    }

    public EntityChildrenClassBean() {
        log.info("开始进行初始化实体的构建 >> ");
        List<Class> sonClass = ClassUtil.getSonClass(CommonEntity.class);
        for (Class clazz : sonClass) {
            boolean annotationPresent = clazz.isAnnotationPresent(TableName.class);
            if (annotationPresent) {
                TableName annotation = (TableName) clazz.getAnnotation(TableName.class);
                String value = annotation.value().toLowerCase();
                this.entityClass.put(value, clazz);
                log.info("实体：{} 构建完毕", value);
            }
        }
        log.info("实体构建完毕, 本次共构建：{} 个实体", entityClass.size());
        terminalSolve();
        warningInfo();
        if (entityClass.size() == 0) {
            log.info("通过扫描类加载构建实体失败，开始启动应急方法");
            log.info("当前通过Map中获取到{}个 实体", preEntityClass.size());
            this.entityClass.putAll(preEntityClass);
        }
    }

    /**
     * 类初始化
     */
    private void initClass(Class clazz) {
        TableName annotation = (TableName) clazz.getAnnotation(TableName.class);
        this.preEntityClass.put(annotation.value().toLowerCase(), clazz);
    }


    /**
     * 信息警告，如果有缺失的程序终止
     */
    private void warningInfo() {
        int preSize = this.preEntityClass.size();
        int entityClassSize = this.entityClass.size();
        if (entityClassSize != 0) {
            if (preSize != entityClassSize) {
                log.error("===========================");
                log.error("警告: 当前扫描到{}个实体类,集合中却只有{}个类", entityClassSize, preSize);
                log.error("所缺失的类名如下：");
                getMissingClassName();
                log.error("程序开始终止");
                log.error("============================");
                System.exit(0);
            }
        }
    }

    /**
     * 查找所缺失的类
     */
    private void getMissingClassName() {
        List<String> preEntityClassList = new ArrayList<>();
        List<String> entityClassList = new ArrayList<>();
        Map<String, Class> preEntityClass = this.preEntityClass;
        Map<String, Class> entityClass = this.entityClass;
        preEntityClass.forEach((k, v) -> preEntityClassList.add(k));
        entityClass.forEach((k, v) -> entityClassList.add(k));
        List<String> collect = entityClassList.stream().filter(num -> !preEntityClassList.contains(num))
                .collect(Collectors.toList());
        collect.forEach(r -> log.error("表名：{}", r));
    }
}
